package com.moyun.common.generator;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.moyun.controller.common.CommonController;
import com.moyun.model.common.CommonFieldEntity;
import org.apache.ibatis.jdbc.ScriptRunner;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @ClassName CodeGenerator
 * @Description 代码生成(mybatis - plus - generator.version 3.5.1 以上为此代码)
 * 官方文档地址：https://baomidou.com/guide/generator-new.html#%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8
 * @Author yangboxuan
 * @Date 2021/10/11 23:10
 */
public class CodeGenerator2 {

    /**
     * 数据源配置
     */
//    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
//            .Builder("jdbc:mysql://8.142.64.42:3306/moyun-base?serverTimezone=GMT%2B8", "root", "Moyun@123");

    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
            .Builder("jdbc:mysql://127.0.0.1:3306/moyun-base?serverTimezone=GMT%2B8", "root", "root");

    public static void main(String[] args) {

        FastAutoGenerator
                .create(DATA_SOURCE_CONFIG)
                /**
                 * 全局配置
                 */
                .globalConfig((scanner, builder) -> builder
                        .author(scanner.apply("请输入作者名称？"))//作者名,默认值:作者
                        //.commentDate("yyyy-MM-dd")//注释日期,默认值: yyyy-MM-dd
                        //.dateType(DateType.TIME_PACK)//时间策略,DateType.ONLY_DATE 默认值: DateType.TIME_PACK
                        .disableOpenDir()//禁止打开输出目录,默认值:true
                        //.enableKotlin()//开启 kotlin 模式,默认值:false
                        .enableSwagger()//开启 swagger 模式,默认值:false
                        //.fileOverride()//覆盖已生成文件,默认值:false
                        .outputDir(System.getProperty("user.dir").concat("/src/main/java"))//指定输出目录,默认值:windows:D:// linux or mac : /tmp
                        .build())
                /**
                 * 包配置
                 */
                .packageConfig((scanner, builder) -> builder
                        // 父包名 lg: cn.ybx.springsecuritydemo
                        .parent(scanner.apply("请输入包名？"))
                        // 父包模块名 lg: sso 最终生成文件所处位置 cn.ybx.springsecuritydemo.sso
                        .moduleName(scanner.apply("请输入模块名？"))
                        //.controller("xx")//Controller包名,默认值:controller
                        //.service("xx")//Service包名,默认值:service
                        //.serviceImpl("xx")//Service Impl包名,默认值:service.impl
                        //.mapper("xx")//Mapper 包名,默认值:mapper
                        //.xml("xx")//Mapper XML 包名,默认值:mapper.xml
                        .entity("pojo.entity")//Entity 包名,默认值:entity
                        //.other("xx")//自定义文件包名,输出自定义文件时所用到的包名
                        .build()
                )
                /**
                 * 策略配置(五类配置：全局策略配置、实体策略配置、controller 策略配置、service 策略配置、mapper 策略配置)
                 */
                .strategyConfig((scanner, builder) -> builder
                        /**
                         * 全局策略配置
                         */
                        .addInclude(getTables(scanner.apply("请输入表名，多个英文逗号分隔？所有输入 all")))//增加表匹配(内存过滤)

                        .build()
                        /**
                         * 实体策略配置
                         */
                        .entityBuilder()
                        .addSuperEntityColumns("creater", "create_time", "modifier", "modify_time")//添加父类公共字段
                        //.addIgnoreColumns("xx")//添加忽略字段
                        .addTableFills(new Column("creater", FieldFill.INSERT))//添加表字段填充
                        .addTableFills(new Column("create_time", FieldFill.INSERT))//添加表字段填充
                        .addTableFills(new Column("modifier", FieldFill.INSERT_UPDATE))//添加表字段填充
                        .addTableFills(new Column("modify_time", FieldFill.INSERT_UPDATE))//添加表字段填充
                        //.addTableFills(new Property("modifyTime", FieldFill.INSERT_UPDATE))//添加表字段填充
                        .columnNaming(NamingStrategy.underline_to_camel)//数据库表字段映射到实体的命名策略,默认为 null，未指定按照 naming 执行
                        //.convertFileName(null)//转换文件名称
                        //.disableSerialVersionUID()//禁用生成serialVersionUID,默认值:true
                        //.enableActiveRecord()//开启 ActiveRecord 模型,默认值:false
                        .enableChainModel()//开启链式模型,默认值:false
                        //.enableColumnConstant()//开启生成字段常量,默认值:false
                        .enableLombok()//开启lombok模型,默认值:false
                        //.enableRemoveIsPrefix()//开启Boolean类型字段移除 is 前缀,默认值:false
                        .enableTableFieldAnnotation()//开启生成实体时生成字段注解,默认值:false
//                        .formatFileName("%s")//格式化文件名称
                        .idType(IdType.AUTO)//全局主键类型
                        .logicDeleteColumnName("is_delete")//逻辑删除字段名(数据库)
                        .logicDeletePropertyName("delete")//逻辑删除属性名(实体)
                        //.nameConvert(null)//名称转换实现
                        .naming(NamingStrategy.underline_to_camel)//数据库表映射到实体的命名策略,默认下划线转驼峰命名:NamingStrategy.underline_to_camel
                        //.versionColumnName("version")//乐观锁字段名(数据库)
                        //.versionPropertyName("version")//乐观锁属性名(实体)
                        //.superClass("")//设置父类
                        .superClass(CommonFieldEntity.class)
                        .build()
                        /**
                         * controller策略配置
                         */
                        .controllerBuilder()
                        //.convertFileName(null)//转换文件名称
                        //.enableHyphenStyle()//开启驼峰转连字符 默认值:false
                        //.enableRestStyle()//开启生成@RestController控制器 默认值:false
//                        .formatFileName("%sController")//格式化文件名称
                        .superClass(CommonController.class)
                        .build()
                        /**
                         * service 策略配置
                         */
                        .serviceBuilder()
                        //.convertServiceFileName(null)//转换service接口文件名称
                        //.convertServiceImplFileName(null)//转换service实现类文件名称
                        .formatServiceFileName("%sService")//格式化service接口文件名称
//                        .formatServiceImplFileName("%sServiceImpl")//格式service实现类文件名称
                        //.superServiceClass("")//设置service接口父类
                        //.superServiceImplClass("")//设置service实现类父类
                        .build()
                        /**
                         * mapper 策略配置
                         */
                        .mapperBuilder()
                        //.cache(null)//设置缓存实现类
                        //.convertMapperFileName(null)//转换mapper类文件名称
                        //.convertXmlFileName(null)//转换xml文件名称
                        .enableBaseColumnList()//启动BaseColumnList生成,默认值:false
                        .enableBaseResultMap()//启用BaseResultMap生成,默认值:false
                        //.enableMapperAnnotation()//开启@Mapper注解,默认值:false
//                        .formatMapperFileName("%sMapper")//格式化mapper文件名称
//                        .formatXmlFileName("%sMapper")//格式化xml实现类文件名称
                        //.superClass("")//设置父类
                        .build()


                )
                /**
                 模板引擎配置，默认 Velocity 可选模板引擎 Beetl 或 Freemarker
                 .templateEngine(new BeetlTemplateEngine())
                 .templateEngine(new FreemarkerTemplateEngine())
                 */
                .templateConfig((scanner, builder) -> builder
                        .controller("/templates/controller2.java")
                        /*.disable(TemplateType.ENTITY)
                        .entity("/templates/entity.java")
                        .service("/templates/service.java")
                        .serviceImpl("/templates/serviceImpl.java")
                        .mapper("/templates/mapper.java")
                        .mapperXml("/templates/mapper.xml")*/
                        .build())

                .execute();

    }

    // 处理 all 情况
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }

    /**
     * 执行初始化数据库脚本(未进行测试)
     */
    public static void before() throws SQLException {
        Connection conn = DATA_SOURCE_CONFIG.build().getConn();
        //具体看项目初始话sql的位置
        InputStream inputStream = CodeGenerator2.class.getResourceAsStream("/sql/init.sql");
        ScriptRunner scriptRunner = new ScriptRunner(conn);
        scriptRunner.setAutoCommit(true);
        scriptRunner.runScript(new InputStreamReader(inputStream));
        conn.close();
    }


}
